using System;

namespace UnitTesting.Fixturing
{
	class CompositeSimpleValueProvider
	{
		Type _simpleType;
		readonly ISimpleTypeGenerator _simpleTypeGenerator;
		readonly StaticCompositeValueProvider _compositeSimpleTypeValueProvider;

		public CompositeSimpleValueProvider(ISimpleTypeGenerator simpleTypeGenerator)
		{
			_simpleTypeGenerator = simpleTypeGenerator;
			_compositeSimpleTypeValueProvider = InitCompositeSimpleTypeValueProvider();
		}

		StaticCompositeValueProvider InitCompositeSimpleTypeValueProvider()
		{
			return new StaticCompositeValueProvider(
				// numbers
				new FactoryValueProvider<SByte>(() => SimpleValues.CreateSbyte(CreateNumber())),
				new FactoryValueProvider<byte>(() => SimpleValues.CreateByte(CreateNumber())),
				new FactoryValueProvider<Int16>(() => SimpleValues.CreateInt16(CreateNumber())),
				new FactoryValueProvider<UInt16>(() => SimpleValues.CreateUInt16(CreateNumber())),
				new FactoryValueProvider<int>(() => SimpleValues.CreateInt(CreateNumber())),
				new FactoryValueProvider<UInt32>(() => SimpleValues.CreateUInt32(CreateNumber())),
				new FactoryValueProvider<Int64>(() => SimpleValues.CreateInt64(CreateNumber())),
				new FactoryValueProvider<UInt64>(() => SimpleValues.CreateUInt64(CreateNumber())),
				new FactoryValueProvider<Single>(() => SimpleValues.CreateSingle(CreateNumber())),
				new FactoryValueProvider<Double>(() => SimpleValues.CreateDouble(CreateNumber())),
				new FactoryValueProvider<Decimal>(() => SimpleValues.CreateDecimal(CreateNumber())),
				//
				new FactoryValueProvider<char>(() => SimpleValues.CreateCharFromAtoZ(CreateNumber())),
				new FactoryValueProvider<bool>(() => SimpleValues.CreateTrueOrFalse(CreateNumber())),
				new FactoryValueProvider<string>(() => SimpleValues.CreateAnonymousString(CreateNumber())),
				new FactoryValueProvider<DateTime>(() => SimpleValues.CreateDateTime(CreateNumber()))
				);
		}

		internal object CreateSimpleValue(Type simpleType)
		{
			_simpleType = simpleType;
			return _compositeSimpleTypeValueProvider.Create(simpleType);
		}

		int CreateNumber()
		{
			return _simpleTypeGenerator.Next(_simpleType);
		}
	}
}